package com.jt.redis.auth.config;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //初始化密码加密对象，后面要使用
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**这个bean定义认证管理器对象，这个对象负责完成用户信息的认证
     * 判定用户信息的合法性，在基于oauth2协议完成认证时，需要此对象，
     * 所以需要将此对象交给spring管理
     * */
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    /**在此类中定义登录的规则
     * 1.对所有的请求放行
     * 2.登录成功的信息
     * 3.登录失败的信息
     * 4.提取公共代码成一个方法
     * */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        super.configure(http);
        //配置认证规则
        //1.禁用跨域攻击，若关闭报403错误
        http.csrf().disable();
        //2.放行所有的请求
        http.authorizeRequests().anyRequest().permitAll();
        //3.自定义登录成功以及失败的逻辑
        http.formLogin()
                .successHandler(successHandler())
                .failureHandler(failureHandler());

    }
    @Bean
    public AuthenticationFailureHandler failureHandler() {
//        return new AuthenticationFailureHandler() {
//            @Override
//            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
//
//            }
//        }
        return (Request,Response,e) -> {
            Map<String,Object> map = new HashMap<>();
            map.put("status", 500);
            map.put("message", "文件上传失败！");
            writeJsonToClient(Response,map);
        };
    }

    @Bean
    public AuthenticationSuccessHandler successHandler() {
//        return new AuthenticationSuccessHandler() {
//            @Override
//            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//
//            }
//        }
        return (Request,Response,authentication) -> {
            Map<String,Object> map = new HashMap<>();
            map.put("status", 200);
            map.put("message", "文件上传成功！");
            writeJsonToClient(Response,map);
        };
    }

    public void writeJsonToClient(HttpServletResponse response, Map<String, Object> map) throws IOException {
        //将map对象转为json串
        String json = new ObjectMapper().writeValueAsString(map);
        //响应编码格式
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        //将数据响应到客户端
        PrintWriter printWriter = response.getWriter();
        printWriter.println(json);
        printWriter.flush();
    }
}
